"""
MicroPython machine module type stubs.

This file provides type hints for the machine module to enable IntelliSense in VS Code.
Place this file in your project's stubs directory and configure python.analysis.extraPaths.
"""

from typing import Callable, Optional, Union

class Pin:
    """Control I/O pins."""

    # Pin modes
    IN: int = 0
    OUT: int = 1
    OPEN_DRAIN: int = 2

    # Pin pull modes
    PULL_UP: int = 1
    PULL_DOWN: int = 2

    # IRQ triggers
    IRQ_FALLING: int = 2
    IRQ_RISING: int = 1
    IRQ_LOW_LEVEL: int = 4
    IRQ_HIGH_LEVEL: int = 8

    def __init__(
        self,
        id: Union[int, str],
        mode: int = -1,
        pull: int = -1,
        *,
        value: Optional[int] = None,
        drive: Optional[int] = None,
        alt: int = -1
    ) -> None:
        """
        Initialize a pin.

        Args:
            id: Pin number or pin name (e.g., 2 or 'GPIO2')
            mode: Pin.IN, Pin.OUT, or Pin.OPEN_DRAIN
            pull: Pin.PULL_UP or Pin.PULL_DOWN
            value: Initial value (0 or 1) if mode is OUT
            drive: Output drive strength (0-3)
            alt: Alternative function

        Example:
            >>> led = Pin(2, Pin.OUT)
            >>> button = Pin(0, Pin.IN, Pin.PULL_UP)
        """
        ...

    def value(self, x: Optional[int] = None) -> int:
        """
        Get or set the pin value.

        Args:
            x: Value to set (0 or 1). If None, returns current value.

        Returns:
            Current pin value (0 or 1)

        Example:
            >>> led.value(1)  # Turn on
            >>> led.value(0)  # Turn off
            >>> state = led.value()  # Read current state
        """
        ...

    def on(self) -> None:
        """Set pin to high (1)."""
        ...

    def off(self) -> None:
        """Set pin to low (0)."""
        ...

    def mode(self, mode: Optional[int] = None) -> int:
        """Get or set pin mode."""
        ...

    def pull(self, pull: Optional[int] = None) -> int:
        """Get or set pin pull mode."""
        ...

    def irq(
        self,
        handler: Optional[Callable] = None,
        trigger: int = IRQ_FALLING | IRQ_RISING,
        *,
        priority: int = 1,
        wake: Optional[int] = None,
        hard: bool = False
    ) -> Callable:
        """
        Configure interrupt handler for the pin.

        Args:
            handler: Callback function to call on interrupt
            trigger: IRQ_RISING, IRQ_FALLING, IRQ_LOW_LEVEL, or IRQ_HIGH_LEVEL
            priority: Interrupt priority (1-7, 1 is highest)
            wake: Wake from sleep mode
            hard: Use hardware interrupt

        Example:
            >>> def callback(pin):
            ...     print('Button pressed!')
            >>> button.irq(handler=callback, trigger=Pin.IRQ_FALLING)
        """
        ...


class ADC:
    """Analog to Digital Converter."""

    # Attenuation levels (ESP32)
    ATTN_0DB: int = 0    # 0-1.1V
    ATTN_2_5DB: int = 1  # 0-1.5V
    ATTN_6DB: int = 2    # 0-2.2V
    ATTN_11DB: int = 3   # 0-3.6V

    # Bit width (ESP32)
    WIDTH_9BIT: int = 0
    WIDTH_10BIT: int = 1
    WIDTH_11BIT: int = 2
    WIDTH_12BIT: int = 3

    def __init__(self, pin: Union[int, Pin]) -> None:
        """
        Initialize ADC on a pin.

        Args:
            pin: Pin number or Pin object

        Example:
            >>> adc = ADC(Pin(34))
            >>> adc = ADC(34)
        """
        ...

    def read(self) -> int:
        """
        Read analog value.

        Returns:
            Raw ADC value (0-4095 for 12-bit)

        Example:
            >>> value = adc.read()
            >>> voltage = value / 4095 * 3.3
        """
        ...

    def read_u16(self) -> int:
        """
        Read analog value as unsigned 16-bit.

        Returns:
            ADC value (0-65535)
        """
        ...

    def atten(self, attenuation: int) -> None:
        """
        Set attenuation level (ESP32 only).

        Args:
            attenuation: ATTN_0DB, ATTN_2_5DB, ATTN_6DB, or ATTN_11DB
        """
        ...

    def width(self, width: int) -> None:
        """
        Set ADC bit width (ESP32 only).

        Args:
            width: WIDTH_9BIT, WIDTH_10BIT, WIDTH_11BIT, or WIDTH_12BIT
        """
        ...


class PWM:
    """Pulse Width Modulation."""

    def __init__(
        self,
        dest: Union[int, Pin],
        *,
        freq: Optional[int] = None,
        duty: Optional[int] = None,
        duty_u16: Optional[int] = None,
        duty_ns: Optional[int] = None
    ) -> None:
        """
        Initialize PWM on a pin.

        Args:
            dest: Pin number or Pin object
            freq: Frequency in Hz
            duty: Duty cycle (0-1023)
            duty_u16: Duty cycle (0-65535)
            duty_ns: Duty cycle in nanoseconds

        Example:
            >>> pwm = PWM(Pin(5), freq=1000, duty=512)
        """
        ...

    def freq(self, value: Optional[int] = None) -> int:
        """
        Get or set PWM frequency.

        Args:
            value: Frequency in Hz

        Returns:
            Current frequency in Hz
        """
        ...

    def duty(self, value: Optional[int] = None) -> int:
        """
        Get or set duty cycle (0-1023).

        Args:
            value: Duty cycle value

        Returns:
            Current duty cycle
        """
        ...

    def duty_u16(self, value: Optional[int] = None) -> int:
        """Get or set duty cycle (0-65535)."""
        ...

    def duty_ns(self, value: Optional[int] = None) -> int:
        """Get or set duty cycle in nanoseconds."""
        ...

    def deinit(self) -> None:
        """Deinitialize PWM."""
        ...


class Timer:
    """Hardware timer."""

    ONE_SHOT: int = 0
    PERIODIC: int = 1

    def __init__(self, id: int) -> None:
        """
        Initialize timer.

        Args:
            id: Timer ID (0-3 on most platforms)
        """
        ...

    def init(
        self,
        *,
        mode: int = PERIODIC,
        period: int = -1,
        freq: Optional[float] = None,
        callback: Optional[Callable] = None
    ) -> None:
        """
        Configure timer.

        Args:
            mode: ONE_SHOT or PERIODIC
            period: Period in milliseconds
            freq: Frequency in Hz
            callback: Function to call on timer event

        Example:
            >>> def tick(t):
            ...     print('Tick!')
            >>> tim = Timer(0)
            >>> tim.init(period=1000, callback=tick)
        """
        ...

    def deinit(self) -> None:
        """Deinitialize timer."""
        ...


class I2C:
    """I2C bus communication."""

    def __init__(
        self,
        id: int,
        *,
        scl: Union[int, Pin],
        sda: Union[int, Pin],
        freq: int = 400000
    ) -> None:
        """
        Initialize I2C bus.

        Args:
            id: I2C bus ID (0 or 1)
            scl: SCL pin
            sda: SDA pin
            freq: Frequency in Hz (default 400kHz)
        """
        ...

    def scan(self) -> list[int]:
        """
        Scan for I2C devices.

        Returns:
            List of device addresses found
        """
        ...

    def readfrom(self, addr: int, nbytes: int) -> bytes:
        """Read bytes from device."""
        ...

    def writeto(self, addr: int, buf: bytes) -> int:
        """Write bytes to device."""
        ...


class SPI:
    """SPI bus communication."""

    def __init__(
        self,
        id: int,
        *,
        baudrate: int = 1000000,
        polarity: int = 0,
        phase: int = 0,
        bits: int = 8,
        firstbit: int = 0,
        sck: Optional[Pin] = None,
        mosi: Optional[Pin] = None,
        miso: Optional[Pin] = None
    ) -> None:
        """Initialize SPI bus."""
        ...

    def read(self, nbytes: int, write: int = 0x00) -> bytes:
        """Read bytes from SPI."""
        ...

    def write(self, buf: bytes) -> int:
        """Write bytes to SPI."""
        ...


class UART:
    """UART serial communication."""

    def __init__(
        self,
        id: int,
        baudrate: int = 9600,
        bits: int = 8,
        parity: Optional[int] = None,
        stop: int = 1,
        *,
        tx: Optional[Pin] = None,
        rx: Optional[Pin] = None
    ) -> None:
        """Initialize UART."""
        ...

    def read(self, nbytes: Optional[int] = None) -> Optional[bytes]:
        """Read bytes from UART."""
        ...

    def write(self, buf: bytes) -> int:
        """Write bytes to UART."""
        ...


# Module-level functions

def reset() -> None:
    """Perform a hard reset of the device."""
    ...


def soft_reset() -> None:
    """Perform a soft reset (like Ctrl+D in REPL)."""
    ...


def reset_cause() -> int:
    """
    Get the reset cause.

    Returns:
        Reset cause constant
    """
    ...


def freq(hz: Optional[int] = None) -> int:
    """
    Get or set CPU frequency.

    Args:
        hz: New frequency in Hz

    Returns:
        Current CPU frequency
    """
    ...


def unique_id() -> bytes:
    """
    Get unique device identifier.

    Returns:
        Unique ID as bytes
    """
    ...


def idle() -> None:
    """Reduce power consumption until next interrupt."""
    ...


def sleep() -> None:
    """Enter sleep mode (platform dependent)."""
    ...


def deepsleep(time_ms: int = 0) -> None:
    """
    Enter deep sleep mode.

    Args:
        time_ms: Sleep duration in milliseconds (0 = indefinite)
    """
    ...


def lightsleep(time_ms: int = 0) -> None:
    """Enter light sleep mode."""
    ...


def time_pulse_us(
    pin: Pin,
    pulse_level: int,
    timeout_us: int = 1000000
) -> int:
    """
    Time a pulse on a pin.

    Returns:
        Pulse duration in microseconds
    """
    ...
